<script setup lang='ts'>
import {ref, CSSProperties, watch, Directive, reactive} from 'vue'
import {FormProps, FormEmits} from './dFrom'
import dIcon from '@/components/dIcon.vue'
import type {ElForm} from 'element-plus'
import zhCN from 'ant-design-vue/es/locale/zh_CN'
import { SeleteData} from '@/api/config'
import useConfig from '@/store/config'

const config = useConfig.setup().store
const props = defineProps(FormProps)
const emits = defineEmits(FormEmits)
type FormInstance=InstanceType<typeof ElForm>
const formRef = ref<FormInstance>()

const clearEmpty = () => {
  const form = props.formData
  for (const key in form) {
    const data = form[key]
    if (data === '') form[key] = undefined
  }
}
//提交表单
const onSubmit = () => {
  const elForm = formRef.value
  if (!elForm) return
  elForm.validate((valid) => {
    if (valid) {
      if (props.clearEmpty) {
        clearEmpty()
      }
      emits('submit')
    }
    else {
      return false
    }
  })
}
//清除表单
const resetForm = () => {
  const elForm = formRef.value
  if (!elForm) return
  elForm.resetFields()
}

//样式
const getStyle = (lineNum:number, rowGap:number, colGap:number) => {
  const style:CSSProperties = {}
  style['grid-template-columns'] = `repeat(${lineNum},1fr)`
  style.rowGap = rowGap + 'px'
  style.columnGap = colGap + 'px'
  style.paddingBottom = '16px'
  return style
}

const getSelectTitle = (value:string|number|null|undefined, seleteData:Array<SeleteData>):string => {
  if (value === null || value === undefined) {
    return ''
  } else {
    for (let i = 0, l = seleteData.length; i < l; i++) {
      if (seleteData[i].value === value) {
        return seleteData[i].label
      }
    }
    return ''
  }
}

watch(
  () => props.resetFieldsFlag,
  () => {
    resetForm()
  }
)

watch(
  () => props.validateFlag,
  () => {
    onSubmit()
  }
)

//elinput聚焦
const onElFocus = (el:HTMLDivElement) => {
  //el的input在三层
  if (el.children[0] && el.children[0].children[0]) {
    const input = el.children[0].children[0] as HTMLInputElement
    input.focus()
  }
}

//elinput聚焦
const vElFocus:Directive<HTMLDivElement, boolean|undefined> = {
  mounted(el, focus) {
    if (focus.value) {
      onElFocus(el)
    }
  }
}

</script>

<template>
  <el-form
    ref="formRef"
    :class="[{'d-common-grid':display==='grid'},{'d-common-flex-row d-common-flex-waper':display==='flex'}]"
    :style="getStyle(formLineNum,rowGap,colGap)"
    :rules="rules"
    :model="formData"
    :label-position="labelPosition"
    :label-width="labelWidth"
    @submit.prevent
  >
    <template v-for="formitem in formItems" :key="formitem.name">
      <el-form-item v-if="!formitem.hideItem" :label="formitem.label" :prop="formitem.prop" :class="formitem.class" :style="formitem.style">
        <el-input
          v-if="formitem.type==='input'&&!formitem.hideItem"
          v-model="formData[formitem.prop]"
          v-el-focus="formitem.autofocus"
          :type="formitem.inputType"
          :title="formData[formitem.prop]"
          :clearable="!formitem.notClearable"
          :placeholder="formitem.placeholder"
          :disabled="formitem.disabled"
          :show-password="formitem.showPassword"
          :autofocus="formitem.autofocus"
          :maxlength="formitem.maxlength"
          @keyup.enter="formitem.enterSubmit?onSubmit():null"
        />

        <el-input-number
          v-else-if="formitem.type==='inputNumber'&&!formitem.hideItem"
          v-model="formData[formitem.prop]"
          v-el-focus="formitem.autofocus"
          controls-position="right"
          class="d-input-text-left"
          :max="formitem.max"
          :min="formitem.min"
          :step-strictly="!formitem.notStrictly"
          :clearable="!formitem.notClearable"
          :step="formitem.step"
          :placeholder="formitem.placeholder"
          :disabled="formitem.disabled"
          :autofocus="formitem.autofocus"
          @keyup.enter="formitem.enterSubmit?onSubmit():null"
        />
        <el-select
          v-else-if="formitem.type==='selete'&&!formitem.hideItem"
          v-model="formData[formitem.prop]"
          :title="getSelectTitle(formData[formitem.prop],formitem.seleteData)"
          :clearable="!formitem.notClearable"
          :multiple="formitem.multiple"
          :multiple-limit="formitem.multipleLimit"
          :collapse-tags="formitem.multiple"
          :filterable="formitem.filterable"
          :placeholder="formitem.placeholder"
          :disabled="formitem.disabled"
          :remote="formitem.remoteConfig&&formitem.remoteConfig.remote"
          :remote-method="formitem.remoteConfig&&formitem.remoteConfig.remoteMethod?formitem.remoteConfig.remoteMethod:undefined"
          :loading="formitem.remoteConfig&&formitem.remoteConfig.loading"
          @change="formitem.changeSubmit?onSubmit():null"
        >
          <el-option v-for="item in formitem.seleteData" :key="''+item.value" :label="item.label" :value="item.value" />
        </el-select>
        <el-select
          v-else-if="formitem.type==='seleteIcon'"
          v-model="formData[formitem.prop]"
          :clearable="!formitem.notClearable"
          :multiple="formitem.multiple"
          :multiple-limit="formitem.multipleLimit"
          :collapse-tags="formitem.multiple"
          :filterable="formitem.filterable"
          :placeholder="formitem.placeholder"
          :disabled="formitem.disabled"
          @change="formitem.changeSubmit?onSubmit():null"
        >
          <el-option v-for="item in formitem.seleteData" :key="item" :label="item" :value="item">
            <d-icon class="d-common-icon-theme" :icon-config="{icon:item,type:'custom',color:config.basic.colors.theme}" />
          </el-option>
        </el-select>
        <el-select-v2
          v-else-if="formitem.type==='seleteV2'&&!formitem.hideItem"
          v-model="formData[formitem.prop]"
          :title="getSelectTitle(formData[formitem.prop],formitem.seleteData)"
          :options="formitem.seleteData"
          :clearable="!formitem.notClearable"
          :multiple="formitem.multiple"
          :collapse-tags="formitem.multiple"
          :filterable="formitem.filterable"
          :placeholder="formitem.placeholder"
          :disabled="formitem.disabled"
          :remote="formitem.remoteConfig&&formitem.remoteConfig.remote"
          :remote-method="formitem.remoteConfig&&formitem.remoteConfig.remoteMethod?formitem.remoteConfig.remoteMethod:undefined"
          :loading="formitem.remoteConfig&&formitem.remoteConfig.loading"
          @change="formitem.changeSubmit?onSubmit():null"
        />
        <el-tree-select
          v-else-if="formitem.type==='seleteTree'&&!formitem.hideItem"
          v-model="formData[formitem.prop]"
          :data="formitem.seleteData"
          :clearable="!formitem.notClearable"
          :multiple="formitem.multiple"
          :collapse-tags="formitem.multiple"
          :show-checkbox="formitem.showCheckbox"
          :check-strictly="formitem.checkStrictly"
          :placeholder="formitem.placeholder"
          :disabled="formitem.disabled"
          @change="formitem.changeSubmit?onSubmit():null"
        />
        <el-radio-group v-else-if="formitem.type==='radio'&&!formitem.hideItem" v-model="formData[formitem.prop]" :disabled="formitem.disabled">
          <el-radio v-for="data in formitem.seleteData" :key="''+data.value" :label="data.value">
            {{ data.label }}
          </el-radio>
        </el-radio-group>
        <a-config-provider v-else-if="formitem.type==='antdDate'&&!formitem.hideItem" :locale="zhCN">
          <A-date-picker
            v-model:value="formData[formitem.prop]"
            :placeholder="formitem.placeholder"
            :allow-clear="!formitem.notClearable"
            :disabled="formitem.disabled"
            :clearable="!formitem.notClearable"
            :format="formitem.dateFormat"
            :value-format="formitem.dateFormat"
            :show-time="formitem.showTime"
            :disabled-date="formitem.disabledDate"
            @open-change="formitem.openChange"
            @calendar-change="formitem.calendarChange"
            @ok="formitem.changeSubmit?onSubmit():null"
          />
        </a-config-provider>
        <a-config-provider v-else-if="formitem.type==='antdRange'&&!formitem.hideItem" :locale="zhCN">
          <A-range-picker
            v-model:value="formData[formitem.prop]"
            :placeholder="formitem.placeholder"
            :allow-clear="!formitem.notClearable"
            :disabled="formitem.disabled"
            :clearable="!formitem.notClearable"
            :format="formitem.dateFormat"
            :value-format="formitem.dateFormat"
            :show-time="formitem.showTime"
            :disabled-date="formitem.disabledDate"
            @open-change="formitem.openChange"
            @calendar-change="formitem.calendarChange"
            @ok="formitem.changeSubmit?onSubmit():null"
          />
        </a-config-provider>
        <slot v-else-if="formitem.type==='slot'&&!formitem.hideItem" :name="formitem.slotName" :form-data="formData" :formitem="formitem" />
      </el-form-item>
    </template>
  </el-form>
</template>

<style scoped>
</style>